package com.huterox.todoscheduler.common.impl;


import com.huterox.todoscheduler.common.SerializationUtils;
import com.huterox.todoscheduler.common.TaskManager;
import com.huterox.todoscheduler.config.Configuration;
import com.huterox.todoscheduler.core.wapper.TaskWrapper;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 任务管理器
 * */
public class DefaultTaskManager implements TaskManager, Serializable {

    private final ThreadPoolExecutor executor;
    private final Map<String, BlockingQueue<Runnable>> taskQueues;
    private final Object lock;

    public DefaultTaskManager(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit) {
        executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, new LinkedBlockingQueue<>());
        taskQueues = new HashMap<>();
        lock = new Object();
    }

    public DefaultTaskManager() {

        executor = new ThreadPoolExecutor(
                Configuration.corePoolSize,
                Configuration.maximumPoolSize,
                Configuration.keepAliveTime,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>());
        taskQueues = new HashMap<>();
        lock = new Object();
    }

    @Override
    public void submitTask(TaskWrapper task, String id) {
        if (id == null || id.isEmpty()) {
            executor.execute(task); // 直接执行任务
            //然后保存当前的一个状态
            saveStatus();
        } else {
            synchronized (lock) {
                BlockingQueue<Runnable> queue = taskQueues.computeIfAbsent(id, k -> new LinkedBlockingQueue<>());

                if (queue.isEmpty()) {
                    // 之前没有相同ID的任务在执行，直接提交到线程池执行
                    executor.execute(() -> {
                        try {
                            task.run(); // 执行任务
                        } finally {
                            submitNextTask(id); // 执行完毕后提交下一个任务
                            saveStatus();
                        }
                    });
                } else {
                    // 将任务加入队列中，等待前面的任务执行完毕后再执行
                    queue.offer(() -> {
                        try {
                            task.run(); // 执行任务
                        } finally {
                            submitNextTask(id); // 执行完毕后提交下一个任务
                            saveStatus();
                        }
                    });
                }
            }
        }
    }

    @Override
    public void saveStatus() {
        //保存当前的一个状态
        SerializationUtils.serializeObject(this,"runningTask","task.ser");
    }

    private void submitNextTask(String id) {
        synchronized (lock) {
            BlockingQueue<Runnable> queue = taskQueues.get(id);
            if (queue != null && !queue.isEmpty()) {
                executor.execute(queue.poll()); // 提交下一个任务
            } else {
                taskQueues.remove(id); // 队列为空时移除对应的ID
            }
        }
    }

    public ThreadPoolExecutor getExecutor() {
        return executor;
    }

    public Map<String, BlockingQueue<Runnable>> getTaskQueues() {
        return taskQueues;
    }

    public Object getLock() {
        return lock;
    }

    @Override
    public void shutdown() {
        executor.shutdown();
    }
}
